package org.jeecg.modules.utils;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.enmu.MessageTypeEnum;
import org.jeecg.modules.vo.Message;


import java.util.List;

@Slf4j
public class MessageEncoder extends MessageToMessageEncoder<Message> {

    private static final int FIXED_HEADER = 0x7E7C6B5A;
    private static final int MESSAGE_SEQ = 1; // 消息序号定义为int类型


    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> out) throws Exception {
        int messageLength = 0;
        if (msg.getBuffer() != null) {
            messageLength = 4 + 4 + 4 + 4 + msg.getBuffer().readableBytes()+2;
        } else {
            messageLength = 4 + 4 + 1 + 4 + 2;
        }
        // 计算总消息长度（包括固定报文头、消息长度、消息类型、消息序号、消息体和CRC16校验码）
        // 固定报文头 + 消息长度 + 消息类型 + 消息序号 + 消息体 + CRC16校验码
        // 创建ByteBuf
        ByteBuf buffer = ctx.alloc().buffer(messageLength);
        // 写入固定报文头
        buffer.writeIntLE(FIXED_HEADER);
        // 写入消息长度
        buffer.writeIntLE(messageLength);
        // 写入消息序号
        buffer.writeIntLE(MESSAGE_SEQ);
        // 写入消息类型
        buffer.writeIntLE(msg.getMessageType());
      /*  //写入消息体
        if (msg.getMessageContent() != null) {
            buffer.writeBytes(msg.getMessageContent());
        }*/
        buffer.writeBytes(msg.getBuffer());
        buffer.writeShort(500);

        // 计算CRC16校验码
        //int crc16Value = calculateCRC16(data, 0, data.length - 2);
        // 写入CRC16校验码
        //buffer.writeShort(crc16Value);
        byte[] data = new byte[messageLength];
        // 将编码后的消息添加到输出列表
        buffer.getBytes(0, data);

        out.add(buffer);
       log.debug("发送消息类型：" + MessageTypeEnum.fromValue(msg.getMessageType()).getDescription());
       log.debug("发送消息类型code：" +msg.getMessageType() );
        //将字节转为hesh
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i++) {
            sb.append(String.format("%02X", data[i] & 0xFF));

        }
       log.debug("发送消息内容：" + sb.toString());


    }

    private String padWithSpaces(String str, int length) {
        if (str.length() >= length) {
            return str.substring(0, length);
        }
        return String.format("%-" + length + "s", str);
    }

    private int calculateCRC16(byte[] data, int offset, int length) {
        int crc = 0xFFFF;
        for (int i = offset; i < offset + length; i++) {
            crc ^= (data[i] & 0xFF);
            for (int j = 0; j < 8; j++) {
                if ((crc & 1) > 0) {
                    crc >>= 1;
                    crc ^= 0xA001;
                } else {
                    crc >>= 1;
                }
            }
        }
        return crc;
    }
}